/* 
 *  include/asm/i386.h
 * 
 *  last modified 2007.07.14 21:53 by ChenJie
 *
 */

#ifndef I386_H
#define I386_H

#include <cos/config.h>

// DA意为描述符属性
#define DA_MASK		(0x00F0FF00)
#define GA_MASK		(0x0000FF00)
#define DA_32			(0x00400000)	//32位段
#define DA_LIMIT_4K	(0x00800000)	//段界限粒度为4KB
#define DA_LIMIT_1B 	(0x00000000)   //段界限粒度为1B

#define DA_DPL0		(0x00000000)	// DPL = 0
#define DA_DPL1		(0x00002000)	// DPL = 1
#define DA_DPL2		(0x00004000)	// DPL = 2
#define DA_DPL3		(0x00006000)	// DPL = 3

#define DA_DPL(n)	(((n)<0)?0x00000000:(((n)>3)?0x00006000:((n)<<13)))

#define DA_DR		(0x00009000)	//存在的只读数据段
#define DA_DRW		(0x00009200)	//存在的可读写数据段
#define DA_DRWA		(0x00009300)	//存在的已访问可读写数据段
#define DA_C		(0x00009800)	//存在的只执行代码段
#define DA_CR		(0x00009A00)	//存在的可执行可读代码段

#define DA_LDT		(0x00008200)	//局部描述符表段
#define DA_CallGate	(0x00008400)   // Call Gate
#define DA_TaskGate	(0x00008500)	//任务门
#define DA_386TSS	(0x00008900)	//任务状态段
#define DA_386CGate	(0x00008C00)	//386调用门
#define DA_386IGate	(0x00008E00)	//386中断门
#define DA_386TGate	(0x00008F00)	//386陷阱门

// SA意为选择子属性
#define SA_RPL0		(0x0000)	// RPL = 0	
#define SA_RPL1		(0x0001)	// RPL = 1
#define SA_RPL2		(0x0002)	// RPL = 2
#define SA_RPL3		(0x0003)	// RPL = 3

#define SA_RPL(n)	(((n)<0)?0x0000:(((n)>3)?0x0003:(n)))

#define SA_TIG		(0x0000)	// 全局选择子
#define SA_TIL		(0x0004)	// 局部选择子

// 分页机制常量说明
#define PG_P		(0x00000001)	// 页存在属性位
#define PG_RWR		(0x00000000) // R/W属性位，读/执行
#define PG_RWW		(0x00000002)	// R/W属性位，读/写/执行
#define PG_USS		(0x00000000)	// U/S属性位，系统级
#define PG_USU		(0x00000004)	// U/S属性位，用户级


//内核代码段选择子：
#define SELECTOR_KCS	((1<<3)+(SA_TIG|SA_RPL0))
//内核数据段选择子：
#define SELECTOR_KDS	((2<<3)+(SA_TIG|SA_RPL0))
//内核堆栈段选择子：
#define SELECTOR_KGS	((3<<3)+(SA_TIG|SA_RPL3))

#define SELECTOR_KSS		((0<<3)+(SA_TIL|SA_RPL0))
//用户态代码段选择子：
#define SELECTOR_UCS(n)		((1<<3)+(SA_TIL|SA_RPL(n)))
//用户态数据段选择子：
#define SELECTOR_UDS(n)		((2<<3)+(SA_TIL|SA_RPL(n)))
//用户态堆栈段选择子：
#define SELECTOR_USS(n)		((3<<3)+(SA_TIL|SA_RPL(n)))

// 描述符说明
#define Descriptor(Base, Limit, Attr) \
	.long ((Limit) & 0x0000ffff)|(((Base)<<16) & 0xffff0000); \
	.long  (((Base)>>16) & 0x00ff)|((Base) & 0xff000000)|((Limit) & 0x000f0000)|((Attr) & DA_MASK);



#endif //I386_H
